package personal.lijun.skeleton.springcloud.gateway.config;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.User;
import personal.lijun.skeleton.springcloud.common.data.security.CurrentLoginUser;
import reactor.core.publisher.Mono;

import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Auther: lijun@sstcsoft.com
 * @Date: 2019-10-14 09:42
 */
@Configuration
public class CustomFilterConfig {

    private final  static Logger logger = LoggerFactory.getLogger(CustomFilterConfig.class);

    @Bean
    GlobalFilter customerGlobalFilter() {
        return (exchange, chain) -> exchange.getPrincipal()
                .map(principal -> {
                    if (principal != null) {
                        ObjectMapper objectMapper = new ObjectMapper();
                        try {
                            CurrentLoginUser currentLoginUser = usernamePasswordAuthenticationToken2CurrentLoginUser((UsernamePasswordAuthenticationToken)principal);
                            String json = objectMapper.writeValueAsString(currentLoginUser);
                            exchange.getRequest().mutate().header("CUSTOM-REQUEST-HEADER", json).build();
                        } catch (JsonProcessingException e) {
                            e.printStackTrace();
                        }
                    }
                    return exchange;
                })
                .flatMap(chain::filter)
                .doOnError(e->{logger.error("序列化json出错",e);});
    }

    private CurrentLoginUser usernamePasswordAuthenticationToken2CurrentLoginUser(UsernamePasswordAuthenticationToken token){
        CurrentLoginUser currentLoginUser = new CurrentLoginUser();
        currentLoginUser.setCredentials(token.getCredentials()==null?(String)null:token.getCredentials().toString());
        User user = (User)token.getPrincipal();
        if(user!=null){
            personal.lijun.skeleton.springcloud.common.data.security.User user2 = new personal.lijun.skeleton.springcloud.common.data.security.User();
            user2.setAccountNonExpired(user.isAccountNonExpired());
            user2.setAccountNonLocked(user.isAccountNonLocked());
            user2.setCredentialsNonExpired(user.isCredentialsNonExpired());
            user2.setUsername(user.getUsername());
            user2.setPassword(user.getPassword());
            user2.setEnabled(user.isEnabled());
            currentLoginUser.setPrincipal(user2);
            Collection<GrantedAuthority> grantedAuthorities = user.getAuthorities();
            List<personal.lijun.skeleton.springcloud.common.data.security.GrantedAuthority> grantedAuthorityList = grantedAuthorities.stream().map(item->{
                personal.lijun.skeleton.springcloud.common.data.security.GrantedAuthority grantedAuthority = new personal.lijun.skeleton.springcloud.common.data.security.GrantedAuthority();
                grantedAuthority.setAuthority(item.getAuthority());
                return  grantedAuthority;
            }).collect(Collectors.toList());
            user2.setAuthorities(grantedAuthorityList);
            currentLoginUser.setPrincipal(user2);
            currentLoginUser.setAuthorities(grantedAuthorityList);
        }
        return  currentLoginUser;
    }
//    @Bean
    public GlobalFilter customGlobalPostFilter() {
        return (exchange, chain) -> chain.filter(exchange)
                .then(Mono.just(exchange))
                .map(serverWebExchange -> {
                    //adds header to response
                    serverWebExchange.getResponse().getHeaders().set("CUSTOM-RESPONSE-HEADER",
                            HttpStatus.OK.equals(serverWebExchange.getResponse().getStatusCode()) ? "It worked": "It did not work");
                    return serverWebExchange;
                })
                .then();
    }
}
